﻿namespace TopHero
{
    public class StateMachine<T>
    {
        private T _owner;
        private State<T> _currentState;
        private State<T> _previousState;
        private State<T> _globalState;

        public StateMachine(T owner)
        {
            _owner = owner;
            _currentState = null;
            _previousState = null;
            _globalState = null;
        }

        void SetCurrentState(State<T> s)
        {
            _currentState = s;
        }

        void SetGlobalState(State<T> s)
        {
            _globalState = s;
        }

        void SetPreviousState(State<T> s)
        {
            _previousState = s;
        }

        public void Update()
        {
            if (_globalState != null)
            {
                _globalState.Execute(_owner);
            }

            if (_currentState != null)
            {
                _currentState.Execute(_owner);
            }
        }

        public bool HandleMessage(Telegram msg)
        {
            if (_currentState != null && _currentState.OnMessage(_owner, msg))
            {
                return true;
            }

            if (_globalState != null && _globalState.OnMessage(_owner, msg))
            {
                return true;
            }

            return false;
        }

        public void ChangeState(State<T> newState)
        {
            Debug.Assert(newState != null, "pNewState != null");
            _previousState = _currentState;

            _currentState?.Exit(_owner);

            _currentState = newState;

            _currentState.Enter(_owner);
        }

        public void RevertToPreviousState()
        {
            ChangeState(_previousState);
        }

        public bool isInState(State<T> state)
        {
            return state.GetType() == _currentState.GetType();
        }
    }
}